package Controller

import (
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"log"
	"strconv"
	"web_back_go/Common"
	"web_back_go/DAO/gorm"
	"web_back_go/DAO/gorm/GormModel"
	"web_back_go/Dto"
	"web_back_go/Response"
	"web_back_go/Service"
)

type AddrParam struct {
	// 地址ID
	AddrId uint64 `json:"addrId" validate:"required"`
	// 收货人
	Receiver string `json:"receiver" validate:"required"`
	// 地址
	Addr string `json:"addr" validate:"required"`
	// 邮编
	PostCode string `json:"postCode"`
	// 手机
	Mobile string `json:"mobile" validate:"required"`
	// 省ID
	ProvinceId uint64 `json:"provinceId" validate:"required"`
	// 城市ID
	CityId uint64 `json:"cityId" validate:"required"`
	// 区ID
	AreaId int64 `json:"areaId" validate:"required"`
	// 省
	Province string `json:"province" validate:"required"`
	// 城市
	City string `json:"city" validate:"required"`
	// 区
	Area string `json:"area" validate:"required"`
}

/*
GetUserDvyList

	@Operation(summary = "用户地址列表" , description = "获取用户的所有地址信息")
*/
func GetUserDvyList(c *gin.Context) {
	token := c.GetHeader("Authorization")
	userId, _, err := Common.CodeToken(token)
	//log.Println(userId)
	if token == "" || err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00004",
			Data:    nil,
			Success: true,
			Msg:     "Unauthorized",
		})
		return
	}
	db := gorm.Db
	var userAddr []GormModel.TzUserAddr
	//List<UserAddr> userAddrs = userAddrService.list(new LambdaQueryWrapper<UserAddr>().eq(UserAddr::getUserId, userId).orderByDesc(UserAddr::getCommonAddr).orderByDesc(UserAddr::getUpdateTime));
	err = db.Raw("SELECT * FROM tz_user_addr WHERE user_id = ? ORDER BY common_addr DESC,update_time DESC", userId).Scan(&userAddr).Error
	if err != nil {
		log.Println(err)
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "服务器异常",
		})
		return
	}
	var userAddrDtoList []Dto.UserAddrDto
	//使用copier.Copy()函数将userAddr切片中的数据复制到userAddrDtoList切片中
	err = copier.CopyWithOption(&userAddrDtoList, &userAddr, copier.Option{IgnoreEmpty: true, DeepCopy: true})
	if err != nil {
		log.Println(err)
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "服务器异常",
		})
		return
	}
	c.JSON(200, Response.ResponseBody{
		Code:    "00000",
		Data:    userAddrDtoList,
		Success: true,
		Msg:     nil,
	})
}

/*
AddressInfo
@Description: 获取地址信息订单配送地址
*/
func AddressInfo(c *gin.Context) {
	addrIdStr := c.Param("addrId")

	addrId, err := strconv.ParseInt(addrIdStr, 10, 64)
	defer func() {
		if err != nil {
			c.JSON(200, Response.ResponseBody{
				Code:    "A00001",
				Data:    nil,
				Success: true,
				Msg:     "服务器异常",
			})
			return
		}
	}()
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "服务器异常",
		})
		return
	}
	UserId, err := Common.GetUserId(c)
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00004",
			Data:    nil,
			Success: true,
			Msg:     "Unauthorized",
		})
		return
	}
	userAddr := Service.GetUserAddrByUserId(addrId, UserId)
	if userAddr == nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "该地址已被删除",
		})
		return
	}
	var userAddrDto Dto.UserAddrDto
	err = copier.CopyWithOption(&userAddrDto, &userAddr, copier.Option{IgnoreEmpty: true, DeepCopy: true})
	c.JSON(200, Response.ResponseBody{
		Code:    "00000",
		Data:    userAddrDto,
		Success: true,
	})
}

/*
AddAddress
@Description: 新增用户地址
*/
func AddAddress(c *gin.Context) {
	addrParam := &AddrParam{}
	err := c.ShouldBindJSON(&addrParam)
	db := gorm.Db.Begin()

	// 延迟回退函数
	defer func() {
		if r := recover(); r != nil {
			db.Rollback()
			c.JSON(200, Response.ResponseBody{
				Code:    "A00005",
				Data:    nil,
				Success: true,
				Msg:     "服务器出了点小差",
			})
		} else if err != nil {
			db.Rollback()
		} else {
			db.Commit()
		}
	}()

	userId, err := Common.GetUserId(c)
	if addrParam.AddrId != 0 {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "该地址已存在",
		})
		return
	}

	var addrCount int64
	db.Model(&GormModel.TzUserAddr{}).Where("user_id = ?", userId).Count(&addrCount)
	var userAddr GormModel.TzUserAddr
	err = copier.CopyWithOption(&userAddr, &addrParam, copier.Option{IgnoreEmpty: true, DeepCopy: true})
	if addrCount == 0 {
		userAddr.CommonAddr = 1
	} else {
		userAddr.CommonAddr = 0
	}
	userAddr.UserID = userId
	userAddr.Status = 1
	userAddr.CreateTime = Common.GetCurrentTime()
	userAddr.UpdateTime = Common.GetCurrentTime()
	db.Save(&userAddr)

	c.JSON(200, Response.ResponseBody{
		Code:    "00000",
		Data:    nil,
		Success: true,
		Msg:     "添加地址成功",
	})
}

/*
DefaultAddress
@Description: 设置默认地址
*/
func DefaultAddress(c *gin.Context) {
	addrIdStr := c.Param("addrId")
	addrId, err := strconv.ParseInt(addrIdStr, 10, 64)
	userId, err := Common.GetUserId(c)
	db := gorm.Db.Begin()
	// 延迟回退函数
	defer func() {
		if r := recover(); r != nil {
			db.Rollback()
			c.JSON(200, Response.ResponseBody{
				Code:    "A00005",
				Data:    nil,
				Success: true,
				Msg:     "服务器出了点小差",
			})
		} else if err != nil {
			db.Rollback()
		} else {
			db.Commit()
		}
	}()
	//先将之前的默认地址设置为非默认
	db.Model(&GormModel.TzUserAddr{}).Where("user_id =?", userId).Update("common_addr", 0)
	//将当前地址设置为默认
	// update tz_user_addr set common_addr = 1 where user_id = #{userId} and addr_id = #{addrId}
	result := db.Model(&GormModel.TzUserAddr{}).Where("user_id =? and addr_id =?", userId, addrId).Update("common_addr", 1)
	rowsAffected := result.RowsAffected
	if rowsAffected == 0 {
		db.Rollback()
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "无法修改用户默认地址，请稍后再试",
			Sign:    nil,
		})
		return
	}

	c.JSON(200, Response.ResponseBody{
		Code:    "00000",
		Data:    nil,
		Success: true,
		Msg:     "修改地址成功",
	})

}

/*
UpdateAddress
修改订单配送地址
*/
func UpdateAddress(c *gin.Context) {
	addrParam := &AddrParam{}
	err := c.ShouldBindJSON(&addrParam)
	log.Printf("addrParam:%+v", addrParam)
	userId, err := Common.GetUserId(c)
	db := gorm.Db.Begin()
	// 延迟回退函数
	defer func() {
		if r := recover(); r != nil {
			db.Rollback()
			c.JSON(200, Response.ResponseBody{
				Code:    "A00005",
				Data:    nil,
				Success: true,
				Msg:     "服务器出了点小差",
			})
		} else if err != nil {
			log.Println(err)
			db.Rollback()
		} else {
			db.Commit()
		}
	}()
	dbUserAddr := &GormModel.TzUserAddr{}
	err = db.Where("user_id = ?", userId).First(dbUserAddr).Error
	if dbUserAddr == nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "该地址已被删除",
		})
		return
	}
	var userAddr GormModel.TzUserAddr
	err = copier.CopyWithOption(&userAddr, &addrParam, copier.Option{IgnoreEmpty: true, DeepCopy: true})

	userAddr.CreateTime = dbUserAddr.CreateTime
	userAddr.UserID = userId
	userAddr.AddrID = dbUserAddr.AddrID
	userAddr.UpdateTime = Common.GetCurrentTime()
	log.Printf("dbUserAddr: %+v\n", dbUserAddr)
	log.Printf("userAddr: %+v", userAddr)
	db.Save(&userAddr)

	if err != nil {
		log.Println(err)
	}
	c.JSON(200, Response.ResponseBody{
		Code:    "00000",
		Data:    nil,
		Success: true,
		Msg:     "修改地址成功",
	})
}

func DeleteAddress(c *gin.Context) {
	addrIdStr := c.Param("addrId")
	addrId, err := strconv.ParseInt(addrIdStr, 10, 64)
	userId, err := Common.GetUserId(c)
	db := gorm.Db.Begin()
	// 延迟回退函数
	defer func() {
		if r := recover(); r != nil {
			db.Rollback()
			c.JSON(200, Response.ResponseBody{
				Code:    "A00005",
				Data:    nil,
				Success: true,
				Msg:     "服务器出了点小差",
			})
		} else if err != nil {
			log.Println(err)
			db.Rollback()
		} else {
			db.Commit()
		}
	}()

	userAddr := Service.GetUserAddrByUserId(addrId, userId)
	if userAddr == nil {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "该地址已被删除",
		})
		return
	}
	if userAddr.CommonAddr == 1 {
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "默认地址不能删除",
		})
		return
	}

	result := db.Where("user_id =? and addr_id =?", userId, addrId).Delete(&GormModel.TzUserAddr{})
	if result.RowsAffected == 0 {
		db.Rollback()
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Data:    nil,
			Success: true,
			Msg:     "该地址已被删除",
		})
		return
	}
	c.JSON(200, Response.ResponseBody{
		Code:    "00000",
		Data:    nil,
		Success: true,
		Msg:     "删除地址成功",
	})
}
